package com.jevons.geo_lib.geojson.adapter;

import androidx.annotation.Keep;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.exception.GeoJsonException;
import com.mapbox.geojson.shifter.CoordinateShifterManager;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Copyright 2020 JxGIS
 *
 * @file BaseCoordinatesTypeAdapter
 * @auth linaisheng
 * Created on 2022/7/13.
 * Description：
 */
@Keep
abstract class BaseCoordinatesTypeAdapter<T> extends TypeAdapter<T> {


    protected void writePoint(JsonWriter out, Point point) throws IOException {
        if (point == null) {
            return;
        }
        writePointList(out, point.coordinates());
    }

    protected Point readPoint(JsonReader in) throws IOException {

        List<Double> coordinates = readPointList(in);
        if (coordinates != null && coordinates.size() > 1) {
            return Point.fromLngLat(coordinates.get(0), coordinates.get(1));
        }

        throw new GeoJsonException(" Point coordinates should be non-null double array");
    }


    protected void writePointList(JsonWriter out, List<Double> value) throws IOException {

        if (value == null) {
            return;
        }

        out.beginArray();

        // Unshift coordinates
        List<Double> unshiftedCoordinates =
                CoordinateShifterManager.getCoordinateShifter().unshiftPoint(value);

        //关键代码，与原始Mapbox的代码不同，GeoJsonUtils.trim()方法将保留7位小数
//        out.value(GeoJsonUtils.trim(unshiftedCoordinates.get(0)));
//        out.value(GeoJsonUtils.trim(unshiftedCoordinates.get(1)));
        out.value(unshiftedCoordinates.get(0));
        out.value(unshiftedCoordinates.get(1));

        // Includes altitude
        if (value.size() > 2) {
            out.value(unshiftedCoordinates.get(2));
        }
        out.endArray();
    }

    protected List<Double> readPointList(JsonReader in) throws IOException {

        if (in.peek() == JsonToken.NULL) {
            throw new NullPointerException();
        }

        List<Double> coordinates = new ArrayList<Double>();
        in.beginArray();
        while (in.hasNext()) {
            coordinates.add(in.nextDouble());
        }
        in.endArray();

        if (coordinates.size() > 2) {
            return CoordinateShifterManager.getCoordinateShifter()
                    .shiftLonLatAlt(coordinates.get(0), coordinates.get(1), coordinates.get(2));
        }
        return CoordinateShifterManager.getCoordinateShifter()
                .shiftLonLat(coordinates.get(0), coordinates.get(1));
    }

}